package main

import (
	"fmt"
	"runtime"
	"sync"
	"time"
)

func Go1() {
	fmt.Println("Go Go Go!!!")
}
func Go2(c chan bool, index int) {
	a := 0
	for i := 0; i < 1000000; i++ {
		a++
	}
	fmt.Println(index, a)
	if index == 9 {
		c <- true
	}
}

func Go3(c chan bool, index int) {
	a := 0
	for i := 0; i < 1000000; i++ {
		a += i
	}
	fmt.Println(index, a)
	c <- true
}
func Go4(wg *sync.WaitGroup, index int) {
	a := 0
	for i := 0; i < 1000000; i++ {
		a += i
	}
	fmt.Println(index, a)
	wg.Done()
}

func Go5(c chan string) {
	i := 0
	for {
		fmt.Println(<-c)
		c <- fmt.Sprintf("Go5 say hi #%d", i)
		i++
	}
}
func main() {
	go Go1()
	time.Sleep(time.Second * 1)

	c := make(chan bool)
	go func() {
		fmt.Println("Go Go Go!!!")
		c <- true
		close(c)
	}()
	for v := range c {
		fmt.Println(v)
	}
	fmt.Println("-----------")

	//没有缓存的channel读写都是阻塞（同步）的
	c1 := make(chan bool)
	go func() {
		fmt.Println("Go Go Go!!!")
		<-c1
	}()
	c1 <- true

	runtime.GOMAXPROCS(runtime.NumCPU())
	//如果只是判断下标，可能会导致，任务没有执行完就结束了，gorouting不保证顺序执行
	//fmt.Println("-----------")
	//for i := 0; i < 10; i++ {
	//	go Go2(c1, i)
	//}
	//<-c1

	// 通过c1中true的数量判断任务是否执行完成
	fmt.Println("-----------")
	for i := 0; i < 10; i++ {
		go Go3(c1, i)
	}
	for i := 0; i < 10; i++ {
		<-c1
	}

	//通过wg判断任务是否实行完成
	fmt.Println("-----------")
	wg := &sync.WaitGroup{}
	wg.Add(10)
	for i := 0; i < 10; i++ {
		go Go4(wg, i)
	}
	wg.Wait()

	//gorouting之间的通信
	fmt.Println("-----------")
	c2 := make(chan string)
	go Go5(c2)
	for i := 0; i < 10; i++ {
		c2 <- fmt.Sprintf("main say hi #%d", i)
		fmt.Println(<-c2)
	}
}
